package com.bangyu.monitor.core.handler;

import com.bangyu.monitor.core.cache.BendMappingCache;
import com.bangyu.monitor.core.util.BendCacuUtil;
import com.bangyu.monitor.core.util.SpringContextUtil;
import com.bangyu.monitor.modular.system.entity.BendMapping;
import com.bangyu.monitor.modular.system.entity.StaticStandDisplayment;
import com.bangyu.monitor.modular.system.model.OriginalDataDto;
import com.bangyu.monitor.modular.system.service.GetBinaryService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @Auther: zhangxue
 * @Date: 19/4/24 13:33
 * @Description:终端每次传来多组(美秒10组或者40组，接收时间需精确到毫秒)数据，
 */
@Slf4j
public class OriginalDataHandler {

    private static int BYTE_LENGTH = 322;//每次传输数据量322个字节


    /**
     * 新设备
     * 将传过来的二进制数据解析成原始值
     * 每次传输数据322个字节
     * 共20组数据，每组数据有8个通道数据，每个通道数据2个字节
     * 最后2个字节为温度
     * @param payLoad
     * @return
     */
    public static List<OriginalDataDto>  newDevicehandler(byte[] payLoad,String deviceNo){
        log.info("数据长度{}",payLoad.length);
        GetBinaryService getBinaryService = SpringContextUtil.getBean(GetBinaryService.class);
        if(getBinaryService!=null){
            getBinaryService.loadBytes(deviceNo,payLoad);
        }
        List<OriginalDataDto> originalDatas = Lists.newArrayList();//原始数据类表
        if(payLoad.length == BYTE_LENGTH){

            Long receiveTime = null;

            long milliseconds = ((new Date().getTime())/1000)*1000;//精确到千位的毫秒数
            int periodMilliseconds = 50;//每组数据间隔的毫秒数

            byte[] tdBytes = Arrays.copyOfRange(payLoad,0,320);//通道数据
            byte[] temperatureBytes = Arrays.copyOfRange(payLoad,BYTE_LENGTH-2,BYTE_LENGTH);//温度
            Integer temperatureInt = bytes2Int(temperatureBytes);
            Float temperatureFloat = (new BigDecimal(temperatureInt).divide(new BigDecimal(100))).floatValue();

            //将二进制数据转换成160组位移数据
            List<Float> floats = Lists.newArrayList();
            for(int i=0;i<160;i++){
                int ivalue1 = bytes2Int(Arrays.copyOfRange(tdBytes,i*2,(i+1)*2));
                float fvalue = trans2Displayment(ivalue1);
                floats.add(fvalue);
            }
            List<List> twentyGroups = Lists.newArrayList();
            for(int j=0;j<10;j++){
                List<Float> list = floats.subList(j*16,(j+1)*16);
                List list1 = Lists.newArrayList();
                List list2 = Lists.newArrayList();
                for(int k=0;k<list.size();k++){
                    if(k%2==0){
                        list1.add(list.get(k));
                    }else{
                        list2.add(list.get(k));
                    }
                }
                twentyGroups.add(list1);
                twentyGroups.add(list2);
            }

            for(int i=0;i<twentyGroups.size();i++){
                List<Float> l = twentyGroups.get(i);
                //获取相同温度下的静态位移值
                receiveTime = milliseconds+i*periodMilliseconds;

                OriginalDataDto data = new OriginalDataDto()
                        .buildDeviceNo(deviceNo)
                        .buildV0(l.get(0))
                        .buildV1(l.get(1))
                        .buildV2(l.get(2))
                        .buildV3(l.get(3))
                        .buildV4(l.get(4))
                        .buildV5(l.get(5))
                        .buildV6(l.get(6))
                        .buildV7(l.get(7))
                        .buildReceiveTime(receiveTime);
                originalDatas.add(data);

            }
        }
        return originalDatas;
    }
    

    //将电压值转换为位移

    /**
     * 25-(byteValue*25/32768)
     * @param byteValue
     * @return
     */
    private static float trans2Displayment(Integer byteValue){
        BigDecimal byteValueDeci = new BigDecimal(byteValue);
        BigDecimal voltageDeci = byteValueDeci.multiply(new BigDecimal(5)).divide(new BigDecimal(32768),8,BigDecimal.ROUND_HALF_UP);
        BigDecimal result =  new BigDecimal(25).subtract(voltageDeci.multiply(new BigDecimal(5)));
        return result.floatValue();
    }
    private static Integer bytes2Int(byte[] bytes){
        return ((bytes[0] & 0xFF)
                | (bytes[1] & 0xFF) << 8);
//        return byte_int*bytes[0]+bytes[1];
    }

    /**
     * 通过相对值(位移)查找编码对应的挠度值
     * @param beamNo 梁编码
     * @param relativeDisplayment 相对位移
     * @return
     */
    private static BendMapping queryBendValueByDisplayment(String beamNo,Float relativeDisplayment){
        List<BendMapping> bendMappings = BendMappingCache.getCache(beamNo);
        BendMapping bendMapping = null;
        Float minVal = null;

        if(CollectionUtils.isNotEmpty(bendMappings) && relativeDisplayment != null){
            for(BendMapping mapping:bendMappings){

                Float displayment1 = mapping.getDisplayment();
                //相对值差值的绝对值
                BigDecimal difrenceVal = (new BigDecimal(displayment1).subtract(new BigDecimal(relativeDisplayment).abs())).abs();
                if(minVal == null){
                    minVal = difrenceVal.floatValue();
                    bendMapping = mapping;
                }else{
                    if(difrenceVal.compareTo(new BigDecimal(minVal))<0){
                        minVal = difrenceVal.floatValue();
                        bendMapping = mapping;
                    }
                }

            }
        }

        return bendMapping;
    }

    private static Float getTargetDisplayment(StaticStandDisplayment standDisplayment,Float targetTemperature){
        if(standDisplayment == null ||targetTemperature == null){
            return null;
        }
        return BendCacuUtil.cacuTargetDisplaymentFromCurrent(0f,standDisplayment.getZero(),targetTemperature);
    }



}
